package cn.gailvlun.gll.presentation.emotion.drawer

import android.app.Activity
import android.app.Dialog
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.support.v4.app.ActivityOptionsCompat
import android.view.View
import android.view.ViewTreeObserver
import android.widget.ImageView
import android.widget.TextView
import cn.gailvlun.gll.databinding.ItemEmotionPersonalCalendarBinding
import cn.gailvlun.gll.databinding.ItemEmotionPersonalEmotionBinding
import cn.gailvlun.gll.databinding.ItemEmotionPersonalHeaderBinding
import cn.gailvlun.gll.net.HttpMethods
import cn.gailvlun.gll.net.HttpSubscriber
import cn.gailvlun.gll.net.ListRes
import cn.gailvlun.gll.net.emotion.Emotion
import cn.gailvlun.gll.net.emotion.RefreshReq
import cn.gailvlun.gll.net.emotion.UserActiveDateRes
import cn.gailvlun.gll.presentation.base.BaseActivity
import cn.gailvlun.gll.presentation.emotion.RefreshState
import cn.gailvlun.gll.presentation.emotion.core.*
import cn.gailvlun.gll.presentation.emotion.core.BaseViewModel.Companion.PREF_COVER_URI
import cn.gailvlun.gll.presentation.emotion.notification.EmotionNotificationActivity
import cn.gailvlun.gll.presentation.emotion.photo.GalleryActivity
import cn.gailvlun.gll.presentation.emotion.photo.VIEW_NAME_IMAGE
import cn.gailvlun.gll.presentation.emotion.util.EmotionDateUtil
import cn.gailvlun.gll.presentation.emotion.util.Util
import cn.gailvlun.gll.presentation.emotion.widget.CollapseTextView
import cn.gailvlun.gll.presentation.emotion.widget.DividerDecoration
import cn.gailvlun.gll.util.DialogUtil
import cn.gailvlun.gll.util.IsEmpty
import cn.gailvlun.gll.util.RxUtil
import cn.gailvlun.gll.util.SPUtil
import cn.gailvlun.gll.widget.NavigationBarView
import com.haibin.calendarview.CalendarLayout
import com.haibin.calendarview.CalendarView
import com.scwang.smartrefresh.layout.api.RefreshHeader
import io.reactivex.functions.Consumer
import org.joda.time.DateTime
import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormat
import rx_activity_result2.Result
import java.util.*


class EmotionPersonalActivity : ImmersionHeaderActivity() {

    private lateinit var mSelectDate: LocalDate
    val emotionMap = HashMap<LocalDate, MutableList<Emotion>>()
    lateinit var calendarLayout: CalendarLayout
    lateinit var calendarView: CalendarView
    private var mTvActiveData: TextView? = null
    private var mIvCover: ImageView? = null
    lateinit var pd: Dialog

    companion object {

        fun openActivity(activity: BaseActivity) {
            val intent = Intent(activity, EmotionPersonalActivity::class.java)
            activity.startActivity(intent)
        }

    }


    override fun initAdapter(): BaseAdapter<*> {
        return EmotionPersonalAdapter(mContext)

    }

    override fun initViewModel(): BaseViewModel {
        return ViewModelProviders.of(this, ViewModelFactory.getInstance(this, adapter as BaseAdapter<Any>)).get(EmotionPersonalViewModel::class.java)
    }

    override fun getSubclassEnum(): SubclassEnum {
        return SubclassEnum.Personal
    }

    override fun initComponent() {
        super.initComponent()
        binding.rvEmotionList.addItemDecoration(DividerDecoration(mContext))
        adapter.setDecorator { holder, position, viewType ->
            val itemBinding = holder.binding
            
            if (itemBinding is ItemEmotionPersonalEmotionBinding) {
                itemBinding.llTextAndImage?.igvEmotionImage?.setOnPhotoClickListener { iv, photos, position ->
                    val options = ActivityOptionsCompat.makeSceneTransitionAnimation(mContext, itemBinding.llTextAndImage?.igvEmotionImage, VIEW_NAME_IMAGE + "-" + position)
                    GalleryActivity.openActivity(mContext, ArrayList(photos), position, null)
                }
                val emotion = adapter.getData()[position] as Emotion
                itemBinding.rlToolBar?.ctvFunction?.setOnClickListener { view -> (viewModel as EmotionPersonalViewModel).showFunction(view, emotion) }

                itemBinding.llTextAndImage?.ctvContent?.setOnCollapseTextListener(object : CollapseTextView.OnCollapseTextListener {
                    override fun onCollapseText(view: View) {
                        val r = Rect()
                        binding.rvEmotionList.getChildVisibleRect(itemBinding.getRoot(), r, null)
                        if (r.top < 20) {
                            linearLayoutManager.scrollToPositionWithOffset(position, binding.nbv.height)
                        }
                    }
                })

                itemBinding.getRoot().viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                    override fun onGlobalLayout() {
                        (itemBinding).ivMostLight.x = randon.nextInt(itemBinding.getRoot().width).toFloat()
                        (itemBinding).ivMostLight.y = randon.nextInt(itemBinding.getRoot().height).toFloat()
                        (itemBinding).ivSecondLight.x = randon1.nextInt(itemBinding.getRoot().width).toFloat()
                        (itemBinding).ivSecondLight.y = randon1.nextInt(itemBinding.getRoot().height).toFloat()
                        (itemBinding).ivLightDark.x = randon2.nextInt(itemBinding.getRoot().width).toFloat()
                        (itemBinding).ivLightDark.y = randon2.nextInt(itemBinding.getRoot().height).toFloat()
                        itemBinding.getRoot().viewTreeObserver.removeOnGlobalLayoutListener(this)
                    }
                })
            }
            
            if (itemBinding is ItemEmotionPersonalCalendarBinding) {
                calendarLayout = itemBinding.calendarLayout
                calendarView = itemBinding.calendarView
                itemBinding.calendarView.setDrawableProvider { calendar ->
                    val date = calendar.year.toString() + "/" + calendar.month + "/" + calendar.day
                    val localDate = LocalDate.parse(date, DateTimeFormat.forPattern("yyyy/MM/dd"))

                    if (emotionMap != null) {

                        val emotionList = emotionMap[localDate]

                        if (emotionList != null && !emotionList.isEmpty()) {

                            return@setDrawableProvider Util.get10KindsEmotionMiddleIcon(emotionList[0].emotion)
                        }
                    }
                    return@setDrawableProvider null
                }


                itemBinding.llRootCalendar.setOnClickListener { view ->
                    itemBinding.llRootCalendar.isPressed = true
                    EmotionCalendarActivity.openActivity(mContext, object : Consumer<Result<Activity>> {
                        override fun accept(p0: Result<Activity>) {
                            if (p0.resultCode() == RESULT_DELETE) {
                                getCalendarData()
                            }
                        }
                    })
                }
                itemBinding.calendarView.setOnDateSelectedListener { calendar, isClick ->
                    itemBinding.tvCalendarTitle.text = EmotionDateUtil.getCalendarTitle(calendar)
                }
                itemBinding.calendarView.setOnMonthChangeListener { year, month -> }
            }
            
            if (itemBinding is ItemEmotionPersonalHeaderBinding) {

                mTvActiveData = itemBinding.tvActiveData
                mIvCover = itemBinding.ivCover
            }

        }
    }

    override fun onMenuClick(nbv: NavigationBarView) {
        super.onMenuClick(nbv)
        EmotionNotificationActivity.openActivity(mContext, EmotionNotificationActivity.FromActivityEnum.FROM_PERSONAL)
    }

    override fun onHeaderPulling(header: RefreshHeader?, percent: Float, offset: Int, headerHeight: Int, extendHeight: Int) {
        super.onHeaderPulling(header, percent, offset, headerHeight, extendHeight)
        if (mIvCover != null) {
            
            mIvCover!!.scaleY = Math.max(percent, 1f)
            mIvCover!!.scaleX = Math.max(percent, 1f)
        }
        binding.nbv.alpha = 0f
    }

    override fun onHeaderReleasing(header: RefreshHeader?, percent: Float, offset: Int, headerHeight: Int, extendHeight: Int) {
        super.onHeaderReleasing(header, percent, offset, headerHeight, extendHeight)
        if (mIvCover != null) {
            if (percent > 1) {
                mIvCover!!.scaleY = percent
                mIvCover!!.scaleX = percent
            }
        }
        
        if (state !== RefreshState.RELEASED) {
            binding.nbv.alpha = 1f
        }
    }

    override fun createHandler() {
        super.createHandler()
        (viewModel as EmotionPersonalViewModel).setOnDeleteEmotionListener(object : EmotionPersonalViewModel.OnDeleteEmotionListener {
            override fun onDelete(emotion: Emotion) {
                getCalendarData()
                (adapter as EmotionPersonalAdapter).remove(emotion)
            }
        })

    }

    override fun loadData(savedInstanceState: Bundle?) {
        mSelectDate = LocalDate.now()
        pd = DialogUtil.showIndeterminate(mContext)
        adapter.add(null, EmotionPersonalAdapter.Type.HEADER.ordinal)
        adapter.add(null, EmotionPersonalAdapter.Type.Calendar.ordinal)
        adapter.add(null, EmotionPersonalAdapter.Type.EMPTY.ordinal)
        super.loadData(savedInstanceState)
    }

    override fun getData(req: RefreshReq) {
        HttpMethods.getEmotionService()
                .emotionListP(0, DateTime.now().millis / 1000 + 60, null, null)
                .compose(RxUtil.applyScheduler())
                .subscribe(object : HttpSubscriber<ListRes<Emotion>>() {
                    override fun onSuccess(response: ListRes<Emotion>) {
                        binding.invalidateAll()
                        binding.srl.isEnableLoadmore = response.isNext
                        if (response.results.size > 0) {
                            val lastIndex = response.results.size - 1
                            req.id = response.results[lastIndex].id
                        }
                        if (req.isLoadMore) {
                            response.results!!
                                    .filter { it.text != null || it.pics.size > 0 }
                                    .forEach { adapter.add(it, EmotionPersonalAdapter.Type.CONTENT.ordinal) }
                        } else {
                            binding.invalidateAll()
                            adapter.clear()
                            adapter.add(null, EmotionPersonalAdapter.Type.HEADER.ordinal)
                            adapter.add(null, EmotionPersonalAdapter.Type.Calendar.ordinal)
                            getActiveData()
                            getCalendarData()
                            if (IsEmpty.list(response.results)) {
                                adapter.add(null, EmotionPersonalAdapter.Type.EMPTY.ordinal)
                            } else {
                                response.results!!
                                        .filter { it.text != null || it.pics.size > 0 }
                                        .forEach { adapter.add(it, EmotionPersonalAdapter.Type.CONTENT.ordinal) }
                            }
                        }

                        pd.dismiss()
                        binding.srl.finishLoadmore(0)
                        binding.srl.finishRefresh(0)
                    }

                    override fun onFailure(errMsg: String, response: ListRes<Emotion>?, code: Int) {
                        pd.dismiss()
                        DialogUtil.showError(mContext, errMsg)
                        binding.srl.finishLoadmore(0)
                        binding.srl.finishRefresh(0)
                    }
                })
    }


    fun getActiveData() {
        HttpMethods.getEmotionService()
                .userActiveDate
                .compose(RxUtil.applyScheduler())
                .compose(mContext.bindToLifecycle())
                .subscribe(object : HttpSubscriber<UserActiveDateRes>() {
                    override fun onSuccess(userActiveDateRes: UserActiveDateRes) {
                        mTvActiveData?.text = Util.getMyEmotionCount(userActiveDateRes.days, userActiveDateRes.count)
                        if (mIvCover != null) {
                            SPUtil.put(SPUtil.USER, PREF_COVER_URI, userActiveDateRes.background)
                            viewModel.coverUri.set(userActiveDateRes.background)
                        }
                    }

                    override fun onFailure(errMsg: String, response: UserActiveDateRes?, code: Int) {
                        DialogUtil.showError(mContext, errMsg)
                    }
                })
    }

    private fun getCalendarData() {
        val selectDate = LocalDate.now();
        val startDate = LocalDate.parse(selectDate.toString("yyyy-MM-01"))
        val endDate = selectDate
        
        val startMills = startDate.toDateTimeAtStartOfDay().getMillis() / 1000
        
        val endMills = endDate.plusDays(1).toDateTimeAtStartOfDay().getMillis() / 1000

        HttpMethods.getEmotionService()
                .emotionListPWithCalendar(startMills, endMills, 31, "true")
                .compose(RxUtil.applyScheduler())
                .subscribe(object : HttpSubscriber<ListRes<Emotion>>() {
                    override fun onSuccess(response: ListRes<Emotion>?) {
                        
                        emotionMap.clear()
                        for (i in 0 until response?.results?.size!!) {
                            val e = response.results!![i]
                            val date = EmotionDateUtil.dateFormat(e.created)
                            var cacheEmotionListByDate: MutableList<Emotion>? = emotionMap[date]
                            if (cacheEmotionListByDate == null) {
                                cacheEmotionListByDate = ArrayList()
                                emotionMap.put(date, cacheEmotionListByDate)
                            }
                            cacheEmotionListByDate.add(e)
                        }
                        calendarView.notifyPage()

                    }

                    override fun onFailure(errMsg: String?, response: ListRes<Emotion>?, code: Int) {

                    }
                })

    }
}